package m.base.action;

import m.base.model.*;
import m.base.service.StoreInfoService;
import m.base.service.UserInfoService;
import m.base.util.PowerUtil;
import m.common.action.ActionMeta;
import m.common.action.RequestMeta;
import m.common.action.VueResult;
import m.common.model.util.*;
import m.html.VueFormResult;
import m.html.VueListResult;
import m.html.element.Element;
import m.html.element.attr.Align;
import m.html.element.attr.ButtonType;
import m.html.element.other.DisplayItem;
import m.html.form.*;
import m.html.list.ListButton;
import m.html.list.ListElement;
import m.html.list.SuccessMethod;
import m.store.service.GuestInfoService;
import m.store.service.RepositoryInfoService;
import m.system.RuntimeData;
import m.system.cache.CacheUtil;
import m.system.document.DocumentMeta;
import m.system.document.DocumentMethodMeta;
import m.system.document.DocumentParamMeta;
import m.system.exception.MException;
import m.system.util.DateUtil;
import m.system.util.JSONMessage;
import m.system.util.StringUtil;
import manage.model.AdminGroup;
import manage.model.OrgGroupView;
import manage.model.StatusModel;
import manage.util.DictionaryUtil;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@ActionMeta(name = "base/storeInfo",title = "商户信息")
public class StoreInfoAction extends BaseStatusAction{
    private StoreInfo model;
    private UserInfo user;

    /**
     * 商户区域字典 action/base/storeInfo/storeParentDict
     */
    public JSONMessage storeParentDict() throws SQLException, MException {
        List<DisplayItem> ls=new ArrayList<>();
        ModelQueryList.getModelList(AdminGroup.class,new String[]{"oid","name"},null,
            QueryCondition.and(
                QueryCondition.eq("business","B"),
                QueryCondition.eq("type","C"),
                QueryCondition.eq("status", StatusModel.Status_Enable),
                QueryCondition.isEmpty("parent.oid")
            )
        ).forEach(item->ls.add(DisplayItem.value(item.getOid(),item.getName())));
        return DictionaryUtil.toDictData(ls);
    }

    @DocumentMeta(
        method = @DocumentMethodMeta(title = "商户和用户申请"),
        params = {
            @DocumentParamMeta(name = "model.parent.oid",description = "区域",notnull = true,length = 50,dictType = "action/base/storeInfo/storeParentDict"),
            @DocumentParamMeta(name = "model.name",description = "商户名称",notnull = true,length = 20),
            @DocumentParamMeta(name = "model.tel",description = "商户电话",notnull = true,length = 20),
            @DocumentParamMeta(name = "model.address",description = "商户地址",notnull = true,length = 300),
            @DocumentParamMeta(name = "model.description",description = "商户描述",length = 1000),
            @DocumentParamMeta(name = "user.username",description = "登录账号",notnull = true,length = 20),
            @DocumentParamMeta(name = "user.password",description = "登录密码",notnull = true,length = 20),
            @DocumentParamMeta(name = "password",description = "重复密码",notnull = true,length = 20),
            @DocumentParamMeta(name = "user.realname",description = "真实姓名",notnull = true,length = 20),
            @DocumentParamMeta(name = "user.phone",description = "手机号",notnull = true,length = 20)
        }
    )
    @RequestMeta(params = {"password","code"},logTitle = "商户申请",logDescription = "申请商户和用户",transaction = true)
    public JSONMessage doApplyStoreAndUser(String password,String code) throws Exception {
        if(null==model) model=new StoreInfo();
        if(null==user) user=new UserInfo();
        ModelQueryCheck.init(model)
            .checkNotNull("name","请输入商户名称")
            .checkNotNull("tel","请输入商户电话")
            .checkNotNull("parent.oid","请选择区域")
            .checkNotNull("address","请输入商户地址")
            .doCheck(false,true);
        ModelQueryCheck.init(user)
            .checkNotNull("username","请输入登录账号")
            .checkNotNull("password","请输入登录密码")
            .checkNotNull("realname","请输入真实姓名")
            .checkNotNull("phone","请输入手机号")
            .doCheck(false,true);
        if(StringUtil.isSpace(password)) throw new MException(this.getClass(),"请输入重复密码");
        if(!user.getPassword().equals(password)) throw new MException(this.getClass(),"两次密码不一致");
        AppInfo app=CacheUtil.get(AppInfo.class,"");
        if(StringUtil.notSpace(app.getRegisterCode())){
            if(StringUtil.isSpace(code)) throw new MException(this.getClass(),"注册序列号不能为空");
            if(!code.equals(AppInfo.toCodeNumber(app.getRegisterCode(),model.getTel()))) throw new MException(this.getClass(),"注册序列号无效");
        }
        model=getService(StoreInfoService.class).addStoreInfo(model);
        user=getService(UserInfoService.class).addUser(user,model,password);
        model.setCreateUserOid(user.getOid());
        ModelUpdateUtil.updateModel(model,"createUserOid");
        getService(UserInfoService.class).setOperType(user.getOid(),model.getOid(),new String[]{UserInfo.OperType_Store,UserInfo.OperType_Finance,UserInfo.OperType_Stock,UserInfo.OperType_Collect});
        getService(GuestInfoService.class).addSelf(model,user);
        getService(RepositoryInfoService.class).addDefault(model,user);
        return new JSONMessage(0,"申请成功，可使用账号密码登录");
    }

    /**
     * 申请商户和用户页面
     */
    public VueResult toApplyStoreAndUser(){
        AppInfo app=CacheUtil.get(AppInfo.class,"");
        boolean isCode=StringUtil.notSpace(app.getRegisterCode());
        ModelForm form = new ModelForm("商户信息",2);
        form.addItem(
            FormInput.input("商户名称", "model.name").setSpan(2).setRequired(true).setPlaceholder("请输入商户名称"),
            FormInput.input("联系电话", "model.tel").setRequired(true).setPlaceholder("请输入联系电话"),
            FormInput.selectItem("商户区域", "model.parent.oid","action/base/storeInfo/storeParentDict").setRequired(true).setPlaceholder("请选择商户区域"),
            isCode?FormInput.input("注册序列号","code").setSpan(2).setRequired(true).setPlaceholder("请输入注册序列号"):null,
            FormInput.input("地址", "model.address").setSpan(2).setRequired(true).setPlaceholder("请输入地址"),
            FormInput.textarea("商户描述", "model.description").setSpan(2).setPlaceholder("请输入商户描述")
        )
        .addData("model",new StoreInfo())
        .addData("user",new UserInfo())
        .addData("password","")
        .addData("code","")
        .addButton(
            FormButton.pri("申请商户","doApplyStoreAndUser")
        )
        .addMethod(
            FormEvent.backFlag,
            FormEvent.doJson("doApplyStoreAndUser",actionUrl("doApplyStoreAndUser"),"{model:this.model,user:this.user,password:this.password,code:this.code}")
                .success("backFlag")
        );
        ModelForm form2 = new ModelForm("账号信息",2);
        form2.addItem(
            FormInput.input("登录账号", "user.username").setSpan(2).setRequired(true).setPlaceholder("请输入登录账号"),
            FormInput.password("登录密码", "user.password").setRequired(true).setPlaceholder("请输入登录密码"),
            FormInput.password("重复密码", "password").setRequired(true).setPlaceholder("请输入重复密码"),
            FormInput.input("真实姓名", "user.realname").setRequired(true).setPlaceholder("请输入真实姓名"),
            FormInput.input("手机号", "user.phone").setRequired(true).setPlaceholder("请输入手机号")
        );
        AppInfo appInfo=new AppInfo();
        appInfo.setRegisterAlert(app.getRegisterAlert());
        appInfo.setRegisterDescription(app.getRegisterDescription());
        appInfo.setRegisterImage(app.getRegisterImage());
        appInfo.setRegisterTitle(app.getRegisterTitle());
        VueFormResult result=new VueFormResult();
        return result.addForm(form).addForm(form2)
            .setLeftForm(
                new CustomForm(
                    Element.tag("a-typography-title").A(":level","5").E("{{appInfo.registerTitle}}"),
                    Element.tag("div").A("style","height:500px;scroll-y:auto;line-height:1.8;")
                    .E(
                        Element.tag("div").A("v-for","item in appInfo.registerDescription.split('\\\\n')").A("style","text-indent:28px;")
                        .E("{{item}}"),
                        Element.tag("div").A("class","text-center padding-sm")
                        .E(
                            Element.tag("img").A("v-if","appInfo.registerImage.oid")
                            .A(":src","appInfo.registerImage.thumPath").A("style","max-width:100%;")
                            .A("@click","viewImage(appInfo.registerImage)")
                        ),
                        Element.tag("a-alert").A("v-if","appInfo.registerAlert").A("type","warning").A("show-icon")
                        .E(Element.tag("template").A("#message").E("{{appInfo.registerAlert}}"))
                    )
                )
                .addData("appInfo",appInfo),
            200);
    }

    /**
     * 保存商户信息
     */
    @RequestMeta(logTitle = "商户信息",logDescription = "管理员保存商户信息")
    public JSONMessage doSave() throws Exception {
        PowerUtil.verifyPower(getStatusPower());//权限判断
        ModelQueryCheck.init(model)
            .checkNotNull("oid","主键不能为空")
            .checkNotNull("name","请输入商户名称")
            .checkNotNull("tel","请输入商户电话")
            .checkNotNull("address","请输入商户地址")
            .doCheck(false,true);
        ModelCheckUtil.checkUniqueCombine(model, new String[]{"name", "parent.oid"},"商户名称已存在");
        ModelUpdateUtil.updateModel(model,"name","tel","address","description","logoutDate");
        CacheUtil.clear(StoreInfo.class);
        DictionaryUtil.clear(AdminGroup.class);
        CacheUtil.clear(AdminGroup.class);
        CacheUtil.clear(OrgGroupView.class);
        return new JSONMessage(0,"修改成功"+(null!=model.getLogoutDate()?"，已设置商户注销日期！":""));
    }
    /**
     * 保存商户信息
     */
    @RequestMeta(logTitle = "商户信息",logDescription = "保存商户信息")
    public JSONMessage doSaveSelf() throws Exception {
        ModelQueryCheck.init(model)
                .checkNotNull("oid","主键不能为空")
                .checkNotNull("name","请输入商户名称")
                .checkNotNull("tel","请输入商户电话")
                .checkNotNull("address","请输入商户地址")
                .doCheck(false,true);
        PowerUtil.verifyStoreData(model.getOid());
        PowerUtil.verifyPower(PowerUtil.Store);//权限判断
        ModelCheckUtil.checkUniqueCombine(model, new String[]{"name", "parent.oid"},"商户名称已存在");
        ModelUpdateUtil.updateModel(model,"name","tel","address","description","accountDay","repositoryCheck");
        CacheUtil.clear(StoreInfo.class);
        DictionaryUtil.clear(AdminGroup.class);
        CacheUtil.clear(AdminGroup.class);
        CacheUtil.clear(OrgGroupView.class);
        return new JSONMessage(0,"修改成功");
    }
    @RequestMeta(logTitle = "商户信息",logDescription = "立即删除用户所有数据")
    public JSONMessage doExeLogout() throws Exception {
        PowerUtil.verifyPower(getStatusPower());//权限判断
        getService(StoreInfoService.class).deleteAllData(model.getOid());
        return JSONMessage.success("操作成功");
    }
    @RequestMeta(logTitle = "商户信息",logDescription = "执行商户注销准备",params = {"password"})
    public JSONMessage exeLogout(String password) throws Exception {
        PowerUtil.verifyPower(PowerUtil.Store);//权限判断
        if(!PowerUtil.getSessionStore(true).getCreateUserOid().equals(PowerUtil.getSessionUserOid()))
            throw new MException(this.getClass(),"权限不足");

        UserInfo user=new UserInfo();
        user.setOid(PowerUtil.getSessionUserOid());
        user=ModelQueryUtil.getModel(user);
        if(!user.getPassword().equals(StringUtil.toMD5(password))) throw new MException(this.getClass(),"密码错误");
        model=PowerUtil.getSessionStore(true);
        model.setLogoutDate(DateUtil.getAddDate(new Date(),3));
        ModelUpdateUtil.updateModel(model,"logoutDate");
        return JSONMessage.success("操作成功");
    }
    @RequestMeta(logTitle = "商户信息",logDescription = "取消商户注销")
    public JSONMessage cancelLogout() throws Exception {
        PowerUtil.verifyPower(PowerUtil.Store);//权限判断
        model=PowerUtil.getSessionStore(true);
        model.setLogoutDate(null);
        ModelUpdateUtil.updateModel(model,"logoutDate");
        return JSONMessage.success("取消成功");
    }
    public VueResult toLogout() throws Exception {
        PowerUtil.verifyPower(PowerUtil.Store);//权限判断
        UserInfo user=PowerUtil.getSessionUser(true);
        model=PowerUtil.getSessionStore(true);
        if(!user.getOid().equals(model.getCreateUserOid())){
            throw new MException(this.getClass(),"只有创建用户才能注销商户。");
        }
        ModelForm form = new ModelForm("注销商户");
        form.addItem(
            FormHtml.ins("提示",Element.tag("a-alert").A("type","warning").A("show-icon")
                .A("message","确认注销后，系统会在三日后对商家所有数据进行物理删除，无法恢复，请确认后再操作。")).setSpan(3),
            FormInput.password("密码","password").setRequired(true).setSpan(3).setPlaceholder("请输入密码")
        )
        .addData("password","")
        .addButton(
            FormButton.warn("注销商户","exeLogout").setConfirm("确定要注销吗？")
        )
        .addMethod(
            FormEvent.backFlag,
            FormEvent.doJson("exeLogout",actionUrl("exeLogout"),"{password:this.password}")
                .success("backFlag")
        );
        VueFormResult result=new VueFormResult();
        return result.addForm(form);
    }
    public JSONMessage getSessionStore() throws Exception {
        return JSONMessage.success("").push("model",PowerUtil.getSessionStore(true));
    }
    /**
     * 商户信息
     */
    public VueResult storeInfo() throws Exception {
        PowerUtil.verifyPower(PowerUtil.Store);//权限判断
        model=PowerUtil.getSessionStore(true);;
        ModelForm form = new ModelForm("{{model.name}}");
        form.setSubTitle("{{model.parent.name}}");
        form.addItem(
            FormInput.input("联系电话", "model.tel").setRequired(true).setPlaceholder("请输入联系电话"),
            FormInput.input("地址", "model.address").setSpan(2).setRequired(true).setPlaceholder("请输入地址"),
            FormInput.textarea("描述", "model.description").setSpan(3).setPlaceholder("请输入描述"),
            FormInput.radio("仓库审核","model.repositoryCheck","m.base.model.StoreInfo!repositoryCheck"),
            FormInput.radio("账期结束日","model.accountDay","m.base.model.StoreInfo!accountDay").setSpan(2)
        )
        .addData("model",model)
        .addButton(
            FormButton.warn("注销商户","toLogout").setTest("!model.logoutDate")
                .setElse(Element.tag("a-space").E(
                    Element.tag("a-alert").A("type","warning").A("show-icon").A(":message","'商户将在'+formatDate(model.logoutDate,'yyyy年MM月dd日')+'24点删除'"),
                    FormButton.warn("取消注销","cancelLogout").setConfirm("确定要取消吗？")
                )),
            FormButton.pri("保存","doSaveSelf")
        )
        .addMethod(
            FormEvent.backFlag,
            FormEvent.loadData(actionUrl("getSessionStore"),"{}").fillData("model"),
            FormEvent.toModal("toLogout",actionUrl("toLogout"),"{model:this.model}",600)
                .after("loadData"),
            FormEvent.doJson("cancelLogout",actionUrl("cancelLogout"),"{}")
                .success("loadData"),
            FormEvent.doJson("doSaveSelf",actionUrl("doSaveSelf"),"{model:this.model}")
        );
        LoadPage page=new LoadPage("loadLevelInfo","page/base/levelInfo.js","{level:this.model.level.oid,endDate:this.formatDate(this.model.levelEndDate,'yyyy-MM-dd')}");
        page.setMounted("this.loadLevelInfo();");
        VueFormResult result=new VueFormResult();
        return result.addForm(form).addForm(page);
    }
    @RequestMeta(logTitle = "商户信息",logDescription = "修改商户级别")
    public JSONMessage doModifyLevel() throws Exception {
        model.setLevel(CacheUtil.get(LevelInfo.class,model.getLevel().getOid()));
        ModelQueryCheck.init(model)
            .checkNotNull("oid","主键不能为空")
            .checkNotNull("level.oid","请选择级别")
            .checkNotNull("levelEndDate","请输入有效期")
            .doCheck(false,true);
        getService(StoreInfoService.class).setLevel(model.getOid(),model.getLevel().getOid(),DateUtil.add(model.getLevelEndDate(), Calendar.HOUR_OF_DAY,1));
        getService(UserInfoService.class).limitUserNum(model.getOid(),model.getLevel().getUserNum());
        getService(RepositoryInfoService.class).limitRepositoryNum(model.getOid(), model.getLevel().getRepositoryNum());
        return new JSONMessage(0,"修改成功");
    }
    public VueResult toModifyLevel() throws Exception {
        PowerUtil.verifyPower(getStatusPower());//权限判断
        StoreInfo store;
        if(null!=model&&!StringUtil.isSpace(model.getOid())){
            store=ModelQueryList.getModel(model,"*","level.name");
            model=new StoreInfo();
            model.setOid(store.getOid());
            model.setLevel(store.getLevel());
            model.setLevelEndDate(store.getLevelEndDate());
        }else{
            throw new MException(this.getClass(),"商户不存在");
        }
        ModelForm form = new ModelForm("修改级别",2);
        form.addItem(
            FormHtml.inputStyle("商户名称", "{{store.name}}").setSpan(2),
            FormHtml.inputStyle("当前级别", "{{store.level.name}} {{formatDate(store.levelEndDate,'yyyy-MM-dd')}}").setSpan(2),
            FormInput.radio("修改级别","model.level.oid","m.base.model.LevelInfo").setRequired(true).setSpan(2),
            FormInput.date("有效期至","model.levelEndDate").setRequired(true).setSpan(2)
        )
        .addData("model",model)
        .addData("store",store)
        .addButton(
            FormButton.pri("确定","doModifyLevel").setConfirm("确定要调整该商户的级别吗？")
        )
        .addMethod(
            FormEvent.backFlag,
            FormEvent.doJson("doModifyLevel",actionUrl("doModifyLevel"),"{model:this.model}")
                .success("backFlag")
        );
        VueFormResult result=new VueFormResult();
        return result.addForm(form);
    }
    /*
     * 编辑商户
     */
    public VueResult toEdit() throws Exception {
        PowerUtil.verifyPower(getStatusPower());//权限判断
        if(null!=model&&!StringUtil.isSpace(model.getOid())){
            model= ModelQueryList.getModel(model,"*","parent.name");
        }else{
            throw new MException(this.getClass(),"商户不存在");
        }
        ModelForm form = new ModelForm("商户修改",2);
        form.addItem(
            FormInput.input("商户区域", "model.parent.name").setSpan(2).setEdit(false),
            FormInput.input("商户名称", "model.name").setRequired(true).setPlaceholder("请输入商户名称"),
            FormInput.input("联系电话", "model.tel").setRequired(true).setPlaceholder("请输入联系电话"),
            FormInput.input("地址", "model.address").setSpan(2).setRequired(true).setPlaceholder("请输入地址"),
            FormInput.textarea("描述", "model.description").setSpan(2).setPlaceholder("请输入描述"),
            FormInput.date("注销日期","model.logoutDate").setSpan(2).setPlaceholder("设置注销日期后会删除用户所有数据。")
        )
        .addData("model",model)
        .addButton(
            FormButton.pri("保存","doSave")
        )
        .addMethod(
            FormEvent.backFlag,
            FormEvent.doJson("doSave",actionUrl("doSave"),"{model:this.model}")
                .success("backFlag")
        );
        VueFormResult result=new VueFormResult();
        return result.addForm(form);
    }
    /*
     * 商户管理列表
     */
    public VueResult manageList() throws Exception {
        boolean power=PowerUtil.hasPower(getStatusPower());
        VueListResult result=getVueListResult("商户管理列表",StoreInfo.class,actionUrl("manageList"));
        result.setFunction(true,false);
        result.setHeight(-1);
        result.addCol(toIndexColumn());
        result.addCol(toTextColumn("区域", "org.name", 100, true));
        result.addCol(toTextColumn("商户名称", "name", 100, true));
        result.addCol(toTextColumn("商户描述", "description", 100, true));
        result.addCol(toTextColumn("联系电话", "tel", 100, true));
        result.addCol(toTextColumn("地址", "address", 100, true));
        result.addCol(toTextColumn("级别", "level.oid", 100, true).setDictType(LevelInfo.class));
        result.addCol(toDateColumn("结束日期","levelEndDate",100,true));
        result.addCol(toDateColumn("注销日期","logoutDate",100,true));
        result.addCol(toStatusColumn(power, true));
        if(power) {
            result.addCol(toSpaceColumn("操作", 130,
                    ListElement.test("record.logoutDate",
                        ListButton.ajax("立即注销",ButtonType.ERROR,actionUrl("doExeLogout"),SuccessMethod.REFRESH)
                            .addParam("model.oid","oid").setConfirm("确定要立即删除商家所有数据吗？")
                    ),
                    ListElement.elseOther(
                        ListButton.modal("修改", ButtonType.PRIMARY, actionUrl("toEdit"), 800, SuccessMethod.REFRESH)
                            .addParam("model.oid", "oid"),
                        ListButton.modal("调整级别", ButtonType.GHOST, actionUrl("toModifyLevel"), 600, SuccessMethod.REFRESH)
                            .addParam("model.oid", "oid")
                    )
            ).setFixed(Align.RIGHT));
        }
        result.addButton(
            ListButton.modal("申请商户", ButtonType.PRIMARY,actionUrl("toApplyStoreAndUser"),900, SuccessMethod.REFRESH)
        );
        //排序 result.addOrder
        //查询条件 result.addCondition
        result.addCondition(QueryCondition.eq("type",AdminGroup.Type_Org));
        result.addCondition(QueryCondition.eq(new String[]{"dept.oid","oid"}));
        return result;
    }
    @Override
    public StoreInfo getModel() {
        return model;
    }

    public UserInfo getUser() {
        return user;
    }

    public void setUser(UserInfo user) {
        this.user = user;
    }

    @Override
    public String[] getStatusPower() {
        return new String[]{PowerUtil.SysData};
    }

    public void setModel(StoreInfo model) {
        this.model = model;
    }
}
